﻿/***********************************************************************************//*
*  作者: 邹杭特                                                                       *
*  时间: 2021-04-24                                                                   *
*  版本: master_b9fdd5                                                                *
*  功能:                                                                              *
*   - 对外接口                                                                        *
*//************************************************************************************/

using UnityEngine;
using System.Collections.Generic;
using BridgeUI.Model;
using UnityEngine.Events;

namespace BridgeUI
{
    /// <summary>
    /// 界面操作接口
    /// </summary>
    public class UIFacade : IUIFacade
    {
        private UIHandlePool handlePool = new UIHandlePool();
        private event UnityAction<IUIPanel> onCreate;
        private event UnityAction<IUIPanel> onClose;
        protected static UIFacade m_instance;
        public static UIFacade Instence
        {
            get
            {
                if (m_instance == null)
                {
                    m_instance = new UIFacade();
                }
                return m_instance;
            }
        }

        public void Open(string panelName, object data = null)
        {
            this.Open(null, panelName, data);
        }

        public void Open(IUIPanel parentPanel, string panelName, object data = null)
        {
            this.Open(parentPanel, panelName, -1, data);
        }
        public void Open(IUIPanel parentPanel, string panelName, int index, object data = null)
        {
            var handle = handlePool.Allocate(panelName);
            handle.RegistCreate(OnCreate);
            handle.RegistClose(OnClose);
            OpenInternal(handle, parentPanel, panelName, index, data);
        }


        public void Open(string panelName, IPanelVisitor uiData)
        {
            Open(null, panelName, uiData);
        }

        public void Open(IUIPanel parentPanel, string panelName, IPanelVisitor uiData)
        {
            var handle = handlePool.Allocate(panelName);
            object data = null;
            if (uiData != null)
            {
                data = uiData.Data;
                uiData.Binding(handle);
                handle.RegistOnRecover(uiData.Recover);
            }
            OpenInternal(handle, parentPanel, panelName, -1, data);
        }

        private void OpenInternal(UIHandle handle, IUIPanel parent, string panelName, int index, object data = null)
        {
            var currentGroup = parent == null ? null : parent.Group;
            var openOK = false;
            if (currentGroup != null)//限制性打开
            {
                var bridge = currentGroup.OpenPanel(parent, panelName, index);
                if (bridge != null)
                {
                    handle.RegistBridge(bridge);
                }
            }
            else
            {
                var groupList = PanelGroupBase.GetActivePanelGroups();
                foreach (var group in groupList)
                {
                    var bridge = group.OpenPanel(parent, panelName, index);
                    if (bridge != null)
                    {
                        handle.RegistBridge(bridge);
                        openOK = true;
                    }
                }
            }

            if (openOK)
            {
                if (data != null)
                {
                    handle.Send(data);
                }
            }
            else
            {
#if UNITY_EDITOR
                Debug.Log("未打开成功，请检查配制信息");
#endif
            }
        }

        public void Hide(string panelName)
        {
            Hide(null, panelName);
        }

        public void Hide(IPanelGroup currentGroup, string panelName)
        {
            if (currentGroup != null)//限制性打开
            {
                currentGroup.HidePanel(panelName);
            }
            else
            {
                var groupList = PanelGroupBase.GetActivePanelGroups();

                foreach (var group in groupList)
                {
                    group.HidePanel(panelName);
                }
            }
        }

        public void Close(IPanelGroup currentGroup, string panelName)
        {
            if (currentGroup != null)
            {
                currentGroup.ClosePanel(panelName);
            }
            else
            {
                var groupList = PanelGroupBase.GetActivePanelGroups();

                foreach (var group in groupList)
                {
                    group.ClosePanel(panelName);
                }
            }
        }

        public void Close(string panelName)
        {
            Close(null, panelName);
        }

        public bool IsPanelOpen(string panelName)
        {
            bool globleHave = false;

            var groupList = PanelGroupBase.GetActivePanelGroups();

            foreach (var group in groupList)
            {
                globleHave |= group.IsPanelOpen(panelName);
            }
            return globleHave;
        }

        public bool IsPanelOpen<T>(string panelName, out T[] panels)
        {
            var groupList = PanelGroupBase.GetActivePanelGroups();
            var objpanels = new List<T>();
            var findPanel = false;
            foreach (var group in groupList)
            {
                T[] subpanels = null;
                if (group.IsPanelOpen(panelName, out subpanels))
                {
                    objpanels.AddRange(subpanels);
                    findPanel = true;
                }
            }

            if (findPanel)
            {
                panels = objpanels.ToArray();
            }
            else
            {
                panels = null;
            }

            return findPanel;
        }


        public void RegistCreate(UnityAction<IUIPanel> onCreate)
        {
            if (onCreate == null) return;
            this.onCreate -= onCreate;
            this.onCreate += onCreate;
        }

        public void RegistClose(UnityAction<IUIPanel> onClose)
        {
            if (onClose == null) return;
            this.onClose -= onClose;
            this.onClose += onClose;
        }
        public void RemoveCreate(UnityAction<IUIPanel> onCreate)
        {
            if (onCreate == null) return;
            this.onCreate -= onCreate;
        }

        public void RemoveClose(UnityAction<IUIPanel> onClose)
        {
            if (onClose == null) return;
            this.onClose -= onClose;
        }

        private void OnCreate(IUIPanel panel)
        {
            if (this.onCreate != null)
            {
                this.onCreate.Invoke(panel);
            }
        }

        private void OnClose(IUIPanel panel)
        {
            if (this.onClose != null)
            {
                this.onClose.Invoke(panel);
            }
        }
    }
}